﻿using System;
using System.Diagnostics;
using System.Windows.Forms;
using System.Collections;
using ns;
using System.IO;

namespace umodelGUILE
{
    public partial class MainForm : Form
    {
        /// <summary>
        /// INI 접근
        /// </summary>
        private IniUtil mIniUtil = new IniUtil(Constants.INI_PATH);

        /// <summary>
        /// 폴더 경로
        /// </summary>
        private String mFolderName;
        /// <summary>
        /// 파일 이름
        /// </summary>
        private String mFileName;

        /// <summary>
        /// 최종 Arguments
        /// </summary>
        private String mArgOptions;
        /// <summary>
        /// umodel Arguments array
        /// </summary>
        private string[] mOptions;

        public MainForm()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 메인 폼 로드
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MainForm_Load(object sender, EventArgs e)
        {
            mOptions = new string[10]; // umodel Arguments 초기화
            // INI에서 환경설정 로드
            mFolderName = mIniUtil.GetIniValueString(Constants.INI_SECTION_PATH, Constants.INI_KEY_PATH); // 폴더 경로
            if (mIniUtil.GetIniValueBoolean(Constants.INI_SECTION_OPTION, Constants.INI_KEY_MESHES, false)) // meshes 옵션
            {
                checkBoxMeshes.Checked = true;
            }
            else
            {
                checkBoxMeshes.Checked = false;
            }

            if (!mFolderName.Equals(""))
            {
                pathTB.Text = mFolderName;
                folderBrowserDialog1.SelectedPath = mFolderName;
                SetFileListView(mFolderName);
            } // INI에서 받아온 폴더경로 사용
            else
            {
                toolStripStatusLabelFileCount.Text = "0 파일";
            } // INI에 저장되어 있는 폴더 경로가 없을 때
        }

        /// <summary>
        /// 폴더 열기 루틴
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ForderOpenButton_Click(object sender, EventArgs e)
        {
            if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
            {
                pathTB.Text = folderBrowserDialog1.SelectedPath;
                mFolderName = pathTB.Text;

                SetFileListView(mFolderName);
            } // 오픈한 폴더를 사용
        }

        private void folderBrowserDialog1_HelpRequest(object sender, EventArgs e)
        {

        }

        /// <summary>
        /// 파일 보기 루틴
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void fileOpenButton_Click(object sender, EventArgs e)
        {
            FileInfo fileInfoUmodel = new FileInfo(Constants.UMODEL_UMODEL_FILE_NAME);
            FileInfo fileInfoSDL = new FileInfo(Constants.UMODEL_SDL_FILE_NAME);
            if (fileListView.SelectedItems.Count == 0)
            {
                MessageBox.Show("파일이 선택되지 않았습니다.", "오류", MessageBoxButtons.OK, MessageBoxIcon.Error);
            } // 선택된 파일이 없으면 오류
            else if (!(fileInfoUmodel.Exists && fileInfoSDL.Exists))
            {
                UmodelErrorDialog umodelErrorDialog = new UmodelErrorDialog();
                umodelErrorDialog.ShowDialog();
                umodelErrorDialog.Dispose();
            } // umodel 없으면 오류
            else
            {
                mArgOptions = "";
                for (int i = 0; i < 10; i++)
                {
                    mArgOptions += mOptions[i];
                }
                Debug.WriteLine("Arguments : " + mArgOptions);
                System.Diagnostics.Process.Start("umodel.exe", "-path=" + "\"" + mFolderName + "\"" + " " + mFileName + mArgOptions);
            } // Arguments 설정하고 저장된 파일명 사용하여 umodel 호출
        }

        private void fileListView_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (fileListView.SelectedItems.Count != 0)
            {
                mFileName = fileListView.SelectedItems[0].Text;
            } // 파일을 선택할 때마다 파일명 저장
        }

        private void exitButton_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        /// <summary>
        /// 파일 목록 출력
        /// </summary>
        /// <param name="folderName">폴더 경로</param>
        private void SetFileListView(String folderName)
        {
            if (fileListView.Items.Count > 0)
            {
                Debug.WriteLine("File list Exist... clear ListBox.");
                fileListView.Items.Clear();
            } // 파일 리스트가 이미 있으면 초기화
            System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(mFolderName);
            foreach (System.IO.FileInfo f in di.GetFiles())
            {
                if (f.Extension.ToLower().Equals(Constants.GPK))
                {
                    fileListView.Items.Add(new ListViewItem(new string[] {
                        f.Name,
                        f.Length.ToString(),
                        f.LastWriteTime.ToShortDateString() + " " + f.LastWriteTime.ToShortTimeString()}));
                }
            } // 저장된 폴더 경로에서 GPK 파일만 모아서 파일 리스트에 뿌리기
            ResizeColumns(fileListView);
            toolStripStatusLabelFileCount.Text = fileListView.Items.Count.ToString() + " 파일"; // 파일 전체 개수 표기
        }

        /// <summary>
        /// 가장 긴 컬럼에 맞게 너비 자동 조정
        /// </summary>
        /// <param name="lv"></param>
        private void ResizeColumns(ListView lv)
        {
            foreach (ColumnHeader column in lv.Columns)
            {
                column.Width = -2;
            }
        }

        /// <summary>
        /// ColumnClick 이벤트 핸들러
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void fileListView_ColumnClick(object sender, ColumnClickEventArgs e)
        {
            for (int i = 0; i < fileListView.Columns.Count; i++)
            {
                fileListView.Columns[i].Text = fileListView.Columns[i].Text.Replace(" " + Constants.ASC_SYM, "");
                fileListView.Columns[i].Text = fileListView.Columns[i].Text.Replace(" " + Constants.DESC_SYM, "");
            } // 컬럼 이름에 화살표 방향 초기화

            if (this.fileListView.Sorting == SortOrder.Ascending || fileListView.Sorting == SortOrder.None)
            {
                this.fileListView.ListViewItemSorter = new ListViewItemCompare(e.Column, Constants.DESC_STR);
                fileListView.Sorting = SortOrder.Descending;
                fileListView.Columns[e.Column].Text = fileListView.Columns[e.Column].Text + " " + Constants.DESC_SYM;
            } // Desc 내림차순
            else
            {
                this.fileListView.ListViewItemSorter = new ListViewItemCompare(e.Column, Constants.ASC_STR);
                fileListView.Sorting = SortOrder.Ascending;
                fileListView.Columns[e.Column].Text = fileListView.Columns[e.Column].Text + " " + Constants.ASC_SYM;
            } // Asc 오름차순

            fileListView.Sort();
        }

        private void checkBoxMeshes_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBoxMeshes.Checked)
            {
                mOptions[0] = UsingOptions.MESHES;
            } // -meshes 옵션 설정
            else
            {
                mOptions[0] = "";
            }
        }

        /// <summary>
        /// 메인 폼이 종료될 때 설정값들을 INI에 저장한다.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            mIniUtil.SetIniValueString(Constants.INI_SECTION_PATH, Constants.INI_KEY_PATH, mFolderName);
            mIniUtil.SetIniValueBoolean(Constants.INI_SECTION_OPTION, Constants.INI_KEY_MESHES, checkBoxMeshes.Checked ? true : false);
        }

        private void AToolStripMenuItemExit_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void ToolStripMenuItemAbout_Click(object sender, EventArgs e)
        {
            AboutDialog aboutDialog = new AboutDialog();
            aboutDialog.ShowDialog();
            aboutDialog.Dispose();
        }

        private void ToolStripMenuItemUmodel_Click(object sender, EventArgs e)
        {
            FileInfo fileInfoUmodel = new FileInfo(Constants.UMODEL_UMODEL_FILE_NAME);
            FileInfo fileInfoSDL = new FileInfo(Constants.UMODEL_SDL_FILE_NAME);
            if (!(fileInfoUmodel.Exists && fileInfoSDL.Exists))
            {
                UmodelErrorDialog umodelErrorDialog = new UmodelErrorDialog();
                umodelErrorDialog.ShowDialog();
                umodelErrorDialog.Dispose();
            }
            else
            {
                UmodelDialog umodelDialog = new UmodelDialog();
                Cmd cmd = new Cmd(Constants.UMODEL_UMODEL_FILE_NAME);
                umodelDialog.SetComments(cmd.StartCommand("-version").ToString());
                umodelDialog.ShowDialog();
                umodelDialog.Dispose();
            }
        }
    }

    /// <summary>
    /// ListView 정렬
    /// </summary>
    class ListViewItemCompare : IComparer
    {
        private int mColumn;
        public string mSort = Constants.ASC_STR;

        public ListViewItemCompare()
        {
            mColumn = 0;
        }

        /// <summary>
        /// 컬럼과 정렬 기준(asc, desc)을 사용하여 정렬한다.
        /// </summary>
        /// <param name="column">몇 번째 컬럼인가.</param>
        /// <param name="sort">정렬 방법 (asc, desc)</param>
        public ListViewItemCompare(int column, string sort)
        {
            mColumn = column;
            this.mSort = sort;
        }

        public int Compare(object x, object y)
        {
            // StringLogicalComparer 사용해서 숫자도 자연스럽게 정렬한다.
            if (mSort.Equals(Constants.ASC_STR))
            {
                return StringLogicalComparer.Compare(((ListViewItem)x).SubItems[mColumn].Text, ((ListViewItem)y).SubItems[mColumn].Text);
            }
            else
            {
                return StringLogicalComparer.Compare(((ListViewItem)y).SubItems[mColumn].Text, ((ListViewItem)x).SubItems[mColumn].Text);
            }
        }
    }
}
